/** Class providing object types for the virtual world, simple GL_POINT,
    but, e.g., also Spheres, Posts and Discs.

DCN 06-07-2010
*/

#pragma once

#include <vector>
#include <string>
#include <iostream>


namespace Stims // Avoid pollution
{
    // dot type enumerator
    enum ObjType {GLpoint, Sphere, Disc, Post, PostSphere};
}

class CStimObj
{
public:
    CStimObj(const enum Stims::ObjType& eObjType_);
    virtual ~CStimObj(void);


    //// setters
    // GL_POINT
    virtual std::vector<double>&    SetPointColor()         {return SetHelper(_vPointColor, _eObjType==Stims::GLpoint, "Point color", "GLpoint");}
    virtual float&                  SetPointSize()          {return SetHelper(_fPointSize , _eObjType==Stims::GLpoint, "Point size", "GLpoint");}
    // Sphere
    virtual std::vector<double>&    SetSphereColor()        {return SetHelper(_vSphereColor  , _eObjType==Stims::Sphere || _eObjType==Stims::PostSphere, "Sphere color", "Spheres and PostSphere");}
    virtual double&                 SetSphereRadius()       {return SetHelper(_dSphereRadius , _eObjType==Stims::Sphere || _eObjType==Stims::PostSphere, "Sphere radius", "Spheres and PostSphere");}
    // Disc
    virtual std::vector<double>&    SetDiscColor()          {return SetHelper(_vDiscColor  , _eObjType==Stims::Disc, "Disc color", "Disc");}
    virtual double&                 SetDiscRadius()         {return SetHelper(_dDiscRadius , _eObjType==Stims::Disc, "Disc radius", "Disc");}
    // Post
    virtual std::vector<double>&    SetPostColor()          {return SetHelper(_vPostColor  , _eObjType==Stims::Post || _eObjType==Stims::PostSphere, "Post color", "Post and PostSphere");}
    virtual double&                 SetPostRadius()         {return SetHelper(_dPostRadius , _eObjType==Stims::Post || _eObjType==Stims::PostSphere, "Post radius", "Post and PostSphere");}
    virtual double&                 SetPostHeight()         {return SetHelper(_dPostHeight , _eObjType==Stims::Post || _eObjType==Stims::PostSphere, "Post height", "Post and PostSphere");}


    // getters
    virtual const enum Stims::ObjType&  ObjType()       const   {return _eObjType;};

protected:
    void        InitObj();
    
    template <typename T>
    T&          SetHelper(T& tParam_, const bool& bRightStim_, const std::string& sParam_, const std::string& sTypes_)
    {
        if (bRightStim_)
            return tParam_;
        else
        {
            std::cout << sParam_.c_str() << " parameter only for " << sTypes_ << "!" << std::endl;
            throw std::exception("^^ Fatal error, parameter cannot be set for this object type");
        }
    }

protected:
    // object specification
    const enum Stims::ObjType           _eObjType;
    // for all
    GLuint                              _uObj;          // display list containing single instance of Object

    // if Stims::GLpoint:
    std::vector<double>                 _vPointColor;
    float                               _fPointSize;

    // if Stims::Sphere
    std::vector<double>                 _vSphereColor;
    double                              _dSphereRadius;

    // if Stims::Disc
    std::vector<double>                 _vDiscColor;
    double                              _dDiscRadius;

    // if Stims::Post
    std::vector<double>                 _vPostColor;
    double                              _dPostRadius;
    double                              _dPostHeight;
};

